package com.xsomnus.rpc.consumer.net;

import com.alibaba.fastjson.JSONObject;
import com.xsomnus.rpc.common.common.Constants;
import com.xsomnus.rpc.common.config.ZkClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @author @xsomnus666_xiawenye★
 * @since 2019/4/22 0022 16:49
 * 当你发现自己的才华撑不起野心时，就请安静下来学习吧
 */
@Slf4j
@Component
public class ServiceDiscovery {

    @Autowired
    ZkClient zkClient;

    @Autowired
    DefaultConnectionManager connectionManager;

    private volatile List<String> addressList = new ArrayList<>();

    @PostConstruct
    public void init() {
        if (zkClient != null) {
            watchNode();
        }
    }


    private void watchNode() {
        List<String> nodesList = zkClient.watchPathV2(Constants.ZK_REGISTRY_PATH, (client, event) -> {
            log.info("event:" + event.getType() + " | path:" + (null != event.getData() ? event.getData().getPath() : null));
            if (event.getData() != null && event.getData().getData() != null) {
                log.info("发生变化的节点内容为：" + new String(event.getData().getData()));
                addressList.clear();
                getNodeData(zkClient.listChildren(Constants.ZK_REGISTRY_PATH));
                refreshCtx();
            }
        });
        log.debug("nodeList: {}", nodesList);
        getNodeData(nodesList);
        log.debug("已经发现的服务列表: {}", JSONObject.toJSONString(nodesList));
        refreshCtx();
    }

    private void refreshCtx() {
        connectionManager.refreshConnectedServer(addressList);
    }

    private void getNodeData(List<String> nodes) {
        log.debug("{}子节点的数据是: {}", Constants.ZK_REGISTRY_PATH, JSONObject.toJSONString(nodes));
        for (String node :
                nodes) {
            String address = new String(zkClient.getNodeData(Constants.ZK_REGISTRY_PATH + Constants.PATH_DELIMETER + node));
            addressList.add(address);
        }
    }

}
